package de.thwildau.tm.moses.abnf.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import de.thwildau.tm.moses.abnf.abnf.AbnfPackage;
import de.thwildau.tm.moses.abnf.abnf.Alternation;
import de.thwildau.tm.moses.abnf.abnf.BinVal;
import de.thwildau.tm.moses.abnf.abnf.CharVal;
import de.thwildau.tm.moses.abnf.abnf.Concatenation;
import de.thwildau.tm.moses.abnf.abnf.DecVal;
import de.thwildau.tm.moses.abnf.abnf.Group;
import de.thwildau.tm.moses.abnf.abnf.HexVal;
import de.thwildau.tm.moses.abnf.abnf.Option;
import de.thwildau.tm.moses.abnf.abnf.ProseVal;
import de.thwildau.tm.moses.abnf.abnf.Repeat;
import de.thwildau.tm.moses.abnf.abnf.Repetition;
import de.thwildau.tm.moses.abnf.abnf.Rule;
import de.thwildau.tm.moses.abnf.abnf.RuleRef;
import de.thwildau.tm.moses.abnf.abnf.RuleSet;
import de.thwildau.tm.moses.abnf.services.AbnfGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractDelegatingSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("all")
public class AbnfSemanticSequencer extends AbstractDelegatingSemanticSequencer {

	@Inject
	private AbnfGrammarAccess grammarAccess;
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == AbnfPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case AbnfPackage.ALTERNATION:
				if(context == grammarAccess.getAlternationRule()) {
					sequence_Alternation(context, (Alternation) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.BIN_VAL:
				if(context == grammarAccess.getBinValRule() ||
				   context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getNumValRule()) {
					sequence_BinVal(context, (BinVal) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.CHAR_VAL:
				if(context == grammarAccess.getCharValRule() ||
				   context == grammarAccess.getElementRule()) {
					sequence_CharVal(context, (CharVal) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.CONCATENATION:
				if(context == grammarAccess.getConcatenationRule()) {
					sequence_Concatenation(context, (Concatenation) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.DEC_VAL:
				if(context == grammarAccess.getDecValRule() ||
				   context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getNumValRule()) {
					sequence_DecVal(context, (DecVal) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.GROUP:
				if(context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getGroupRule()) {
					sequence_Group(context, (Group) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.HEX_VAL:
				if(context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getHexValRule() ||
				   context == grammarAccess.getNumValRule()) {
					sequence_HexVal(context, (HexVal) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.OPTION:
				if(context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getOptionRule()) {
					sequence_Option(context, (Option) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.PROSE_VAL:
				if(context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getProseValRule()) {
					sequence_ProseVal(context, (ProseVal) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.REPEAT:
				if(context == grammarAccess.getRepeatRule()) {
					sequence_Repeat(context, (Repeat) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.REPETITION:
				if(context == grammarAccess.getRepetitionRule()) {
					sequence_Repetition(context, (Repetition) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.RULE:
				if(context == grammarAccess.getRuleRule()) {
					sequence_Rule(context, (Rule) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.RULE_REF:
				if(context == grammarAccess.getElementRule() ||
				   context == grammarAccess.getRuleRefRule()) {
					sequence_RuleRef(context, (RuleRef) semanticObject); 
					return; 
				}
				else break;
			case AbnfPackage.RULE_SET:
				if(context == grammarAccess.getRuleSetRule()) {
					sequence_RuleSet(context, (RuleSet) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (concatenations+=Concatenation concatenations+=Concatenation*)
	 */
	protected void sequence_Alternation(EObject context, Alternation semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (value+=NUM (value+=NUM+ | maxValue=NUM)?)
	 */
	protected void sequence_BinVal(EObject context, BinVal semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     value=STRING
	 */
	protected void sequence_CharVal(EObject context, CharVal semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.CHAR_VAL__VALUE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.CHAR_VAL__VALUE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getCharValAccess().getValueSTRINGTerminalRuleCall_0(), semanticObject.getValue());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     repetitions+=Repetition+
	 */
	protected void sequence_Concatenation(EObject context, Concatenation semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (value+=NUM (value+=NUM+ | maxValue=NUM)?)
	 */
	protected void sequence_DecVal(EObject context, DecVal semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     alternation=Alternation
	 */
	protected void sequence_Group(EObject context, Group semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.GROUP__ALTERNATION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.GROUP__ALTERNATION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getGroupAccess().getAlternationAlternationParserRuleCall_1_0(), semanticObject.getAlternation());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     ((value+=NUM | value+=HEX) ((value+=NUM | value+=HEX)+ | maxValue=NUM | maxValue=HEX)?)
	 */
	protected void sequence_HexVal(EObject context, HexVal semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     alternation=Alternation
	 */
	protected void sequence_Option(EObject context, Option semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.OPTION__ALTERNATION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.OPTION__ALTERNATION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getOptionAccess().getAlternationAlternationParserRuleCall_1_0(), semanticObject.getAlternation());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     value=ID
	 */
	protected void sequence_ProseVal(EObject context, ProseVal semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.PROSE_VAL__VALUE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.PROSE_VAL__VALUE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getProseValAccess().getValueIDTerminalRuleCall_1_0(), semanticObject.getValue());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (lowerBound=NUM? upperBound=NUM?)
	 */
	protected void sequence_Repeat(EObject context, Repeat semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (repeat=Repeat? element=Element)
	 */
	protected void sequence_Repetition(EObject context, Repetition semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     rule=[Rule|ID]
	 */
	protected void sequence_RuleRef(EObject context, RuleRef semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.RULE_REF__RULE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.RULE_REF__RULE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getRuleRefAccess().getRuleRuleIDTerminalRuleCall_0_1(), semanticObject.getRule());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     rules+=Rule+
	 */
	protected void sequence_RuleSet(EObject context, RuleSet semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID alternation=Alternation)
	 */
	protected void sequence_Rule(EObject context, Rule semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.RULE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.RULE__NAME));
			if(transientValues.isValueTransient(semanticObject, AbnfPackage.Literals.RULE__ALTERNATION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AbnfPackage.Literals.RULE__ALTERNATION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getRuleAccess().getNameIDTerminalRuleCall_0_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getRuleAccess().getAlternationAlternationParserRuleCall_2_0(), semanticObject.getAlternation());
		feeder.finish();
	}
}
